package com.milo.java7.generics;

import org.junit.Test;

/**
 * @author: Milogenius
 * @create: 2019-06-10 15:39
 * @description: 泛型类的演示
 * <p>
 * 此处T可以随便写为任意标识，常见的如T、E、K、V等形式的参数常用于表示泛型
 * 在实例化泛型类时，必须指定T的具体类型
 * </p>
 **/
public class Generic<T> {

    //key这个成员变量的类型为T,T的类型由外部指定
    private T key;

    //泛型构造方法形参key的类型也为T，T的类型由外部指定
    public Generic(T key) {
        this.key = key;
    }

    //泛型方法getKey的返回值类型为T，T的类型由外部指定
    public T getKey() {
        return key;
    }

    public void showKeyValue(Generic<?> obj) {
        System.out.println("泛型测试key value is " + obj.getKey());
    }

    /**
     * 泛型通配符的演示
     */
    @Test
    public void test1() {
        Generic<Integer> gInteger = new Generic<Integer>(123);
        Generic<Number> gNumber = new Generic<Number>(456);

        showKeyValue(gNumber);
        //showKeyValue这个方法编译器会为我们报错：Generic<java.lang.Integer>
        showKeyValue(gInteger);
    }

    @Test
    public void test2() {
        //泛型的类型参数只能是类类型（包括自定义类），不能是简单类型
        //传入的实参类型需与泛型的类型参数类型相同，即为Integer.
        Generic<Integer> genericInteger = new Generic<Integer>(123456);

        //传入的实参类型需与泛型的类型参数类型相同，即为String.
        Generic<String> genericString = new Generic<String>("key_vlaue");
        System.out.println("泛型测试key is " + genericInteger.getKey());
        System.out.println("泛型测试key is " + genericString.getKey());
    }
}
